﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using WisPortal.Core;
using WisPortal.Data;
using System.Xml;
using WisPortal;
using System.Data;
using WisPortal.Controls;

namespace WisPortal.Controllers
{
    /// <summary>
    /// 
    /// </summary>
    public class DataController : Controller
    {
        public const string editViewPath = "~/Views/Data/Edit.cshtml";

        //
        // GET: /Data/

        public ActionResult Index()
        {
            return View();
        }

        public ActionResult List(string config, string viewid)
        {

            return View();
        }

        /// <summary>
        /// Get the component html in a form
        /// </summary>
        /// <param name="config"></param>
        /// <param name="rev"></param>
        /// <param name="formid"></param>
        /// <param name="dataid"></param>
        /// <param name="itemid"></param>
        /// <returns></returns>
        public ActionResult ShowPartialHtml(string config, string rev, string formid, string dataid,string guid)
        {
            DataMapping dm;
            XmlNode formDom;
            PrepareConfigration(config, formid, dataid, out dm, out formDom);
            ViewData.Add("isPatial", true);
            DataFormControl df = new DataFormControl(formDom, ControllerContext, ViewData);
            AJAXResult ar = new AJAXResult(rev, df.GetHtml(guid), null, null, null, NotificationType.Information);
            return Json(ar, JsonRequestBehavior.AllowGet);
        }
        

        /// <summary>
        /// Return an json object contain form HTML shown in dialog
        /// </summary>
        /// <param name="config"></param>
        /// <param name="rev"></param>
        /// <param name="formid"></param>
        /// <param name="dataid"></param>
        /// <returns></returns>
        public ActionResult DialogOpen(string config,string rev, string formid, string dataid)
        {
            //Opened in Dialog flag
            ViewData.Add("isDialog", true);
            
            XmlNode formDom = PrepareData(config,formid, dataid);
            
            DataFormControl df = new DataFormControl(formDom, ControllerContext, ViewData);
            df.ShowInDialog = true;
            return Content(df.GetHtml(null));
            //AJAXResult ar = new AJAXResult(rev, df.GetHtml(null), null, null, null, NotificationType.Information);
            //return Json(ar,JsonRequestBehavior.AllowGet);
        }

        [ValidateInput(false)]
        public ActionResult Edit(string config, string formid,string dataid)
        {
            DataMapping dm = new DataMapping(HttpContext);
            XmlNode formDom;
            PrepareConfigration(config,formid, dataid, out dm, out formDom);
            
            //Adjust action type
            if (HttpContext.Request[Const.SubmitActionType] != null)
            {
                //Insert or update
                dm.ProgressRequest();
            }
            
            PrepareDataSource(dm, formDom);
            return View();
        }

        public ActionResult View(string config, string formid,string dataid)
        {
            DataMapping dm = new DataMapping(this.HttpContext);
            //Find the view node
            XmlDocument configDom = XmlHelper.GetConfigration(config);
            XmlNode formDom = configDom.SelectSingleNode(string.Format("//Form[@guid='{0}']",formid));
            string form = XmlHelper.GetAttributeValue(formDom,"view");
            string type = XmlHelper.GetAttributeValue(formDom,"type").ToLower().Trim();
            if (type.Equals("mvc_view"))
            {
                //MVC View
                ViewData.Add("config", configDom);
                ViewData.Add("dataid", dataid);
                ViewData.Add("form", formDom);

                PrepareDataSource(dm, formDom);
                return View(form);
            }
            else
            {
                return Edit(config,formid,dataid);
            }
        }

        /// <summary>
        /// Delete records
        /// </summary>
        /// <param name="config"></param>
        /// <param name="formid"></param>
        /// <param name="dataid"></param>
        /// <returns></returns>
        public ActionResult Delete(string config,string formid, string dataid)
        {
            DataMapping dm = new DataMapping(HttpContext);
            XmlNode formDom;
            PrepareConfigration(config,formid, dataid, out dm, out formDom);
            AppUIParser parser = new AppUIParser(ControllerContext, ViewData);
            if (formDom != null)
            {
                //Execute delete records
                XmlNode dataSourceNode = formDom.SelectSingleNode(".//DataSource");

                if (dataSourceNode != null)
                {
                    if (dataSourceNode.Attributes["ref"] != null)
                    {
                        XmlDocument dataMappingDom = XmlHelper.GetConfigration(XmlHelper.GetAttributeValue(dataSourceNode, "ref"));
                        if (dataMappingDom != null)
                        {
                            string objectId = XmlHelper.GetAttributeValue(dataSourceNode,"object");
                            XmlNode objectNode = dataMappingDom.SelectSingleNode(string.Format(".//Object[@id='{0}']",objectId));
                            if (objectNode != null)
                            {
                                if(dm.DeleteDataByReference(objectNode) >0)
                                    return Json(new AJAXResult(Const.ActionResult_DeleteSuccesfully, NotificationType.Information), JsonRequestBehavior.AllowGet);
                                else
                                    return Json(new AJAXResult(Const.ActionResult_DeleteFail, NotificationType.Information), JsonRequestBehavior.AllowGet);
                            }
                            else
                                throw new CustomerException("No refernce object found in data mapping xml.\n ref:{0} obj:{1}",
                                    XmlHelper.GetAttributeValue(dataSourceNode, "ref"),
                                    XmlHelper.GetAttributeValue(dataSourceNode, "object"));
                        }
                        else
                            throw new CustomerException("No refernce data mapping object found. ref:{0}", XmlHelper.GetAttributeValue(dataSourceNode, "ref"));
                    }
                    else
                    {
                        XmlNode deleteNode = dataSourceNode.SelectSingleNode("Delete");
                        if (deleteNode != null)
                        {
                            if (dm.DeleteDataBySql(deleteNode) > 0)
                                return Json(new AJAXResult(Const.ActionResult_DeleteSuccesfully, NotificationType.Information), JsonRequestBehavior.AllowGet);
                            else
                                return Json(new AJAXResult(Const.ActionResult_DeleteFail, NotificationType.Information), JsonRequestBehavior.AllowGet);
                        }
                        else
                            throw new CustomerException("No Delete configration found");
                    }
                }
                else
                {
                    throw new CustomerException("No DataSrouce configration found");
                }

            }
            else
            {
                throw new CustomerException("No Form configration found");
            }
        }

        private XmlNode PrepareData(string config, string formid, string dataid)
        {
            DataMapping dm;
            XmlNode formDom;
            PrepareConfigration(config,formid, dataid, out dm, out formDom);
            PrepareDataSource(dm, formDom);
            return formDom;
        }

        private void PrepareConfigration(string config, string formid, string dataid, out DataMapping dm, out XmlNode formDom)
        {
            dm = new DataMapping(this.HttpContext, ViewData);
            //Find the view node
            XmlDocument configDom = XmlHelper.GetConfigration(config);

            formDom = configDom.SelectSingleNode(string.Format("//Form[@guid='{0}']", formid));
            string type = XmlHelper.GetAttributeValue(formDom, "type").ToLower().Trim();

            //MVC View
            ViewData.Add(Const.DefaultConfigKey, configDom);
            ViewData.Add("dataid", dataid);
            ViewData.Add("form", formDom);
        }

        /// <summary>
        /// Prepare the data sources 
        /// </summary>
        /// <param name="dm"></param>
        /// <param name="formDom"></param>
        private void PrepareDataSource(DataMapping dm, XmlNode formDom)
        {
            XmlNodeList dataSourceNodes = formDom.SelectNodes(".//DataSource");
            foreach (XmlNode dataSourceNode in dataSourceNodes)
            {
                dm.SetDataset(dataSourceNode, ViewData);
            }
        }
    }
}
